TOOL.Category = '(MadJawa)'
TOOL.Name = '#Laser'
TOOL.Command = nil
TOOL.ConfigName = ''

TOOL.ClientConVar[ 'material' ] = 'cable/physbeam'
TOOL.ClientConVar[ 'starton' ] = '1'
TOOL.ClientConVar[ 'toggle' ] = '1'
TOOL.ClientConVar[ 'width' ] = '3'
TOOL.ClientConVar[ 'length' ] = '20000'
TOOL.ClientConVar[ 'damage' ] = '2500'
TOOL.ClientConVar[ 'worldweld' ] = '0'
TOOL.ClientConVar[ 'key' ] = '5'
TOOL.ClientConVar[ 'sparks' ] = '1'
TOOL.ClientConVar[ 'model' ] = 'models/props_lab/tpplug.mdl';
TOOL.ClientConVar[ 'modelpitch' ] = '0';
TOOL.ClientConVar[ 'offset' ] = '12.5';

cleanup.Register('lasers')

if ( CLIENT ) then
	language.Add( 'Tool_laser_name', "Laser Spawner" )
	language.Add( 'Tool_laser_desc', 'Spawn a very dangerous laser. Handle with care!' )
	language.Add( 'Tool_laser_0', 'Click where you want to spawn the laser.' )
	
	language.Add( 'Undone_laser', 'Undone Laser' )
	language.Add( 'Cleanup_lasers', "Lasers")
	language.Add( 'Cleaned_lasers', "Cleaned up all Lasers")
	language.Add( 'SBoxLimit_lasers', 'Maximum Lasers Reached' )
end

local laser_beams = {
	{ 'XBeam', 'cable/xbeam', 'cable/xbeam' },
	{ 'Red Laser', 'cable/redlaser', 'cable/redlaser' },
	{ 'Blue Electric', 'cable/blue_elec', 'cable/blue_elec' },
	{ 'PhysBeam', 'cable/physbeam', 'cable/physbeam' },
	{ 'Hydra', 'cable/hydra', 'cable/hydra' },
	{ 'Crystal Beam', 'cable/crystal_beam1', 'cable/crystal_beam1' },
	{ 'Red Laser2', 'effects/redlaser1', 'effects/redlaser1' },
	{ 'Light Rail', 'effects/light_rail_beam1', 'effects/light_rail_beam1' }
	}
		
function TOOL:LeftClick( trace )
	if trace.Entity then
		if trace.Entity:IsPlayer() or trace.Entity:IsNPC() then
			return false
		end
	end
	
	if(CLIENT) then
		return true
	end

	if(!SERVER) then return false end
	
	local ply = self:GetOwner()
	local Pos = trace.HitPos
	local Ang = trace.HitNormal:Angle()

	if ( !self:GetSWEP():CheckLimit( "lasers" ) ) then return false end

	local starton = self:GetClientNumber( 'starton' ) == 1
	local toggle = self:GetClientNumber( 'toggle' ) == 1
	local width = self:GetClientNumber( 'width' )
	local length = self:GetClientNumber( 'length' )
	local damage = self:GetClientNumber( 'damage' )
	local material = self:GetClientInfo( 'material' )
	local worldweld = self:GetClientNumber( 'worldweld' ) == 1
	local sparks = self:GetClientNumber( 'sparks' ) == 1
	local key = self:GetClientNumber( 'key' )
	local model = self:GetClientInfo( 'model' )
	local offset = self:GetClientNumber( 'offset' )
	local pitch = self:GetClientNumber( 'modelpitch' )
	
	Ang.p = Ang.p + pitch
	
	if (trace.Entity:IsValid() and trace.Entity:GetClass() == "madjawa_laser") then
		local Entity = trace.Entity
		Entity.BeamEnt:SetKeyValue("width", width )
		Entity.BeamEnt:SetKeyValue("damage", damage)
		if ( sparks ) then
			Entity.BeamEnt:SetKeyValue("spawnflags", 32)
		else
			Entity.BeamEnt:SetKeyValue("spawnflags", 0)
		end
		return true
	end
	
	ent = MakeLaser( ply, Ang, Pos, key, toggle, starton, sparks, width, length, damage, material, model, offset, pitch )
	
	ent:SetPos( trace.HitPos - trace.HitNormal * ent:OBBMins().z)
	
	if ( trace.Entity:IsValid() or worldweld ) then
		local const = constraint.Weld(ent, trace.Entity,0, trace.PhysicsBone, 0, collision == 0 )
	end
	
	if ( trace.Entity:IsValid() ) then trace.Entity:DeleteOnRemove( ent ) end

	undo.Create('Laser')
		undo.AddEntity( ent )
		undo.AddEntity( const )
		undo.SetPlayer( ply )
	undo.Finish()


	ply:AddCleanup( 'lasers', ent )
	ply:AddCleanup( 'lasers', const )
	
	return true
end

if SERVER then 
    CreateConVar('sbox_maxlasers',10)

	function MakeLaser( ply, Ang, Pos, key, toggle, starton, sparks, width, length, damage, material, model, offset, pitch )
		if ( !ply:CheckLimit( "lasers" ) ) then return nil end
		local ent = ents.Create( 'madjawa_laser' )
		if !ent:IsValid() then return false end
		
		ent:SetModel(model)
		ent:SetKeyValue("width", width)
		ent:SetKeyValue("length", length)
		ent:SetKeyValue("damage", damage)
		ent:SetKeyValue("material", material)
		ent:SetKeyValue("offset", offset)
		ent:SetKeyValue("pitch", pitch)
		if ( sparks ) then
			ent:SetKeyValue("spawnflags", 32)
		else
			ent:SetKeyValue("spawnflags", 0)
		end
		ent:Spawn()
		ent:Activate()
		ent:SetAngles(Ang)
		ent:SetPos(Pos)
		
		ent:GetTable():SetOn( starton )
		ent:GetTable():SetToggle( toggle )
		
		numpad.OnDown( ply, key, "Laser_On", ent )
		numpad.OnUp( ply, key, "Laser_Off", ent )
		
		ply:AddCount('lasers', ent)
		
		return ent
	end
	
	duplicator.RegisterEntityClass( 'madjawa_laser', MakeLaser,  'Ang', 'Pos', 'key', 'toggle', 'starton', 'sparks', 'width', 'length', 'damage', 'material', 'model', 'offset', 'pitch' )
	
end

function TOOL.BuildCPanel( CPanel )
	CPanel:AddControl( "Header", { Text = "#Tool_laser_name", Description = "#Tool_laser_desc" } )
	CPanel:AddControl( "Numpad", { Label = "Key", Command = "laser_key", ButtonSize = 22 } )
	
	CPanel:AddControl( "Slider", { 
		Label = "Width :",
		Type = "Integer",
		Min = 1,
		Max = 50,
		Command = "laser_width"
	} )
	
	CPanel:AddControl( "Slider", { 
		Label = "Length :",
		Type = "Integer",
		Min = 10,
		Max = 20000,
		Command = "laser_length"
	} )
	
	CPanel:AddControl( "Slider", { 
		Label = "Damage :",
		Type = "Integer",
		Min = 0,
		Max = 2500,
		Command = "laser_damage"
	} )
	
	local materials = {}
	materials.Label = "Material"
	materials.Height = 64
	materials.Width = 32
	materials.Rows = 1
	materials.Stretch = 1
	
	local mgo = {}
	for k,r in pairs(laser_beams) do
		mgo[r[1]] = { Material = r[2], laser_material = r[3] }
	end
	materials.Options = mgo
	
	CPanel:AddControl( "MaterialGallery", materials )
	
	CPanel:AddControl( "PropSelect", {
		Label = "Model",
		ConVar = "laser_model",
		Category = "Lasers",
		Models = list.Get( "LaserModels" ) } )
	
	CPanel:AddControl( "CheckBox", {
		Label = "Toggle",
		Command = "laser_toggle"
	}) 	
	CPanel:AddControl( "CheckBox", {
		Label = "Auto-weld to world",
		Description = "Weld the laser even if aiming at the world.",
		Command = "laser_worldweld"
	}) 
	CPanel:AddControl( "CheckBox", {
		Label = "Start on",
		Command = "laser_starton"
	})
	CPanel:AddControl( "CheckBox", {
		Label = "Ending sparks",
		Command = "laser_sparks"
	})
end

list.Set( "LaserModels", "models/props_lab/tpplug.mdl", { laser_offset = 12.1, laser_modelpitch = 0 } )
list.Set( "LaserModels", "models/props_junk/TrafficCone001a.mdl", { laser_offset = 15, laser_modelpitch = 90 } )
list.Set( "LaserModels", "models/props_c17/utilityconnecter006c.mdl", { laser_offset = 25.5, laser_modelpitch = 90 } )
list.Set( "LaserModels", "models/props_combine/breenlight.mdl", { laser_offset = 10.2, laser_modelpitch = 270 } )
list.Set( "LaserModels", "models/props_combine/headcrabcannister01a_skybox.mdl", { laser_offset = 4, laser_modelpitch = 180 } )
list.Set( "LaserModels", "models/props_junk/flare.mdl", { laser_offset = 5.9, laser_modelpitch = 90 } )
list.Set( "LaserModels", "models/props_junk/PopCan01a.mdl", { laser_offset = 3.4, laser_modelpitch = 90 } )

function TOOL:UpdateGhostLaser( ent, player )

	if ( !ent ) then return end
	if ( !ent:IsValid() ) then return end

	local tr 	= utilx.GetPlayerTrace( player, player:GetCursorAimVector() )
	local trace 	= util.TraceLine( tr )
	if (!trace.Hit) then return end
	
	if (trace.Entity && trace.Entity:GetClass() == "madjawa_laser" || trace.Entity:IsPlayer() || trace.Entity:IsNPC()) then
	
		ent:SetNoDraw( true )
		return
		
	end
	
	local Ang = trace.HitNormal:Angle()
	Ang.p = Ang.p + self:GetClientNumber( 'modelpitch' )
	ent:SetAngles( Ang )
	
	ent:SetPos( trace.HitPos - trace.HitNormal * ent:OBBMins().z )
	
	ent:SetNoDraw( false )
	
end


function TOOL:Think()
	local model
	
	model = self:GetClientInfo("model")

	if (!self.GhostEntity || !self.GhostEntity:IsValid() || self.GhostEntity:GetModel() != model) then
		self:MakeGhostEntity( model, Vector(0,0,0), Angle(self:GetClientNumber( 'modelpitch' ),0,0) )
	end
	
	self:UpdateGhostLaser( self.GhostEntity, self:GetOwner() )
	
end
